
package com.hlkj.pay.app.merchant.ext.impl.alipay.ext;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.annotation.Extension;
import com.hlkj.pay.app.merchant.ext.MerchantExtConstant;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelPayOrderQueryContext;
import com.hlkj.pay.app.merchant.ext.dto.order.ChannelRefundPayOrderContext;
import com.hlkj.pay.app.merchant.ext.impl.alipay.AlipayScenePayOrderExtPt;
import com.hlkj.pay.app.merchant.ext.impl.alipay.constant.AliPayExtConstant;
import com.hlkj.pay.app.merchant.ext.impl.alipay.dto.AliPayChannelParams;
import com.hlkj.pay.app.merchant.ext.impl.alipay.dto.AlipayConfig;
import com.hlkj.pay.app.merchant.ext.impl.alipay.handler.AliPayCommonParamsHandle;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAppChannelDO;
import com.hlkj.pay.infrastructure.model.order.PayOrderDO;
import com.hlkj.pay.util.DateUtils;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.json.JSONUtil;
import jodd.util.StringPool;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 主扫统一下单
 * 
 * @author HlpayTeam
 * @date 2024/11/18 13:07
 */
@Slf4j
@Repository
@RequiredArgsConstructor
@Extension(bizId = AliPayExtConstant.PC)
public class AlipayPcPayOrderExtPt extends AlipaySceneCommonPayOrder implements AlipayScenePayOrderExtPt {

    private final AliPayCommonParamsHandle aliPayCommonParamsHandle;

    @Value("${hlkj.domain}")
    private String domain;

    @Override
    public void submitChannelPayOrder(ChannelPayOrderContext channelPayOrderContext) {
        // 判断商户类型
        MerchantAppChannelDO merchantAppChannelDO = channelPayOrderContext.getMerchantAppChannelDO();
        // 是否普通商户
        boolean common = aliPayCommonParamsHandle.commonMer(merchantAppChannelDO);
        // 支付宝配置信息
        CommonResult<AlipayConfig> alipayConfigCommonResult = null;
        // 普通商户
        if(common){
            alipayConfigCommonResult = aliPayCommonParamsHandle.alipayConfig(merchantAppChannelDO.getAppConfigJson());
        }else{
            alipayConfigCommonResult = aliPayCommonParamsHandle.alipayConfig(channelPayOrderContext.getProviderChannelConfigDO().getParamsConfig());
        }
        if(!alipayConfigCommonResult.isSuccess()){
            channelPayOrderContext.setRemark(alipayConfigCommonResult.getMsg());
            channelPayOrderContext.setProcessStatus(false);
            return;
        }
        PayOrderDO payOrderDO = channelPayOrderContext.getPayOrderDO();
        try {
            // 获取AlipayClient
            AlipayClient client = aliPayCommonParamsHandle.initClient(alipayConfigCommonResult.getData());
            // 回调通知地址
            String notifyUrl = null;
            // 响应参数
            AlipayTradePagePayResponse response = null;
            // 请求参数封装
            AlipayTradePagePayModel model = new AlipayTradePagePayModel ();
            model.setSubject(payOrderDO.getSubject());
            model.setTotalAmount(NumberUtil.roundStr(payOrderDO.getAmount().doubleValue(),2));
            model.setOutTradeNo(payOrderDO.getPayOrderNo());
            model.setTimeExpire(DateUtils.dateToString(payOrderDO.getExpiredTime(), DatePattern.NORM_DATETIME_PATTERN));
            model.setProductCode("FAST_INSTANT_TRADE_PAY");
            // 构造请求参数以调用接口
            AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
            request.setBizModel(model);
            // 普通商户
            if(common){
                // 商户回调通知
                notifyUrl = domain + MerchantExtConstant.MERCHANT_TRANS_COMMON_ASYNC_CALLBACK_URL + payOrderDO.getChannelCode() + StringPool.SLASH + payOrderDO.getProviderCode()+ StringPool.SLASH + merchantAppChannelDO.getCode();
                request.setNotifyUrl(notifyUrl);
                log.info("普通商户支付宝PC支付请求参数:{}", JSONUtil.toJsonStr(model));
                response = client.pageExecute(request,"GET");
            }else{
                // 服务商
                AliPayChannelParams aliPayChannelParams = JsonUtils.parseObject(merchantAppChannelDO.getAppConfigJson(), AliPayChannelParams.class);
                notifyUrl = channelPayOrderContext.getNotifyUrl();
                request.setNotifyUrl(notifyUrl);
                request.putOtherTextParam("app_auth_token", aliPayChannelParams.getAppAuthToken());
                log.info("服务商支付宝PC支付请求参数:{}", JSONUtil.toJsonStr(model));
                response = client.pageExecute(request,"GET");
            }
            log.info("支付宝PC支付返回参数:{}", JSONUtil.toJsonStr(response));

            if (response.isSuccess()) {
                channelPayOrderContext.setPayDataType("pay_url");
                channelPayOrderContext.setPayInfo(response.getPageRedirectionData());
            }else{
                channelPayOrderContext.setProcessStatus(Boolean.FALSE);
                channelPayOrderContext.setRemark(response.getSubMsg());
            }
        }catch (Exception e) {
            log.error("支付宝PC支付请求失败 message:{}", e);
            channelPayOrderContext.setRemark("支付宝PC支付请求失败,失败信息" + e.getMessage());
            channelPayOrderContext.setProcessStatus(Boolean.FALSE);
        }
    }

    @Override
    public void queryChannelPayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        commonQueryChannelPayOrder(channelPayOrderQueryContext);
    }

    @Override
    public void closeChannelPayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        commonCloseChannelPayOrder(channelPayOrderQueryContext);
    }

    @Override
    public void queryChannelClosePayOrder(ChannelPayOrderQueryContext channelPayOrderQueryContext) {
        commonQueryChannelClosePayOrder(channelPayOrderQueryContext);
    }

    @Override
    public void refundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        commonRefundChannelPayOrder(channelRefundPayOrderContext);
    }

    @Override
    public void queryRefundChannelPayOrder(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        commonQueryRefundChannelPayOrder(channelRefundPayOrderContext);
    }

    @Override
    public boolean refundApply(ChannelRefundPayOrderContext channelRefundPayOrderContext) {
        return true;
    }

    @Override
    public CommonResult<String> channelOrderCode(ChannelPayOrderContext channelPayOrderContext) {
        return CommonResult.success();
    }
}
